"use client";

import { useMemo, useState } from "react";
import {
  Alert,
  AlertIcon,
  Badge,
  Box,
  Flex,
  HStack,
  Heading,
  Tab,
  TabList,
  TabPanel,
  TabPanels,
  Tabs,
  Text,
  VStack,
} from "@chakra-ui/react";
import { useChatStream } from "@/hooks/useChatStream";
import { useGraphExplorer } from "@/hooks/useGraphExplorer";
import { ChatPanel } from "./chat/ChatPanel";
import { KnowledgeGraph } from "./graph/KnowledgeGraph";
import { NodeDetailsPanel } from "./graph/NodeDetailsPanel";
import { EvidencePanel } from "./graph/EvidencePanel";
import { GraphToolbar } from "./graph/GraphToolbar";
import { GraphLegend } from "./graph/GraphLegend";
import { Sidebar } from "./Sidebar";

/**
 * 2026 Aurora layout — three-pane shell.
 *
 *   Sidebar  |  Chat  |  Workspace (tabbed)
 *
 *   The right "Workspace" pane is the new home for graph + ancillary
 *   inspectors.  Floating glass-cards have been retired in favour of a
 *   tabbed accordion: Graph | Evidence | Lineage | Tool Calls | Stats.
 *   Each tab keeps its own state (the graph canvas remains hot inside
 *   tab #1 so it never re-mounts when the user flips tabs).
 */
export function AppShell() {
  const {
    messages,
    graph,
    setGraph,
    extractor,
    pending,
    conversationId,
    tokenReady,
    error,
    send,
    cancel,
    resetConversation,
  } = useChatStream();

  const explorer = useGraphExplorer({ extractor, graph, setGraph });

  const nodeCount = graph.nodes.length;
  const edgeCount = graph.rels.length;
  const evidenceCount = explorer.evidenceChain.length;
  const toolCalls = useMemo(
    () =>
      messages.flatMap((m) =>
        (m.toolCalls ?? []).map((t) => ({ ...t, messageId: m.id }))
      ),
    [messages]
  );

  const statusAlert = useMemo(
    () => error || explorer.error,
    [error, explorer.error]
  );

  // Auto-jump to the Evidence tab when the user requests evidence on a node.
  const [tabIndex, setTabIndex] = useState(0);

  return (
    <Flex h="100vh" w="100vw" overflow="hidden" bg="bg.canvas">
      <Box display={{ base: "none", lg: "block" }}>
        <Sidebar
          conversationId={conversationId}
          messageCount={messages.filter((m) => m.role !== "system").length}
          graphNodeCount={nodeCount}
          tokenReady={tokenReady}
          onNewConversation={() => {
            resetConversation();
            explorer.clearRoles();
            explorer.clearEvidence();
            explorer.setSelectedNodeId(null);
            setTabIndex(0);
          }}
        />
      </Box>

      <ChatPanel
        messages={messages}
        pending={pending}
        ready={tokenReady}
        error={statusAlert}
        onSend={send}
        onCancel={cancel}
      />

      {/* ───── Right: Workspace pane (tabbed) ───── */}
      <Flex
        direction="column"
        w={{ base: "0", md: "520px", xl: "720px" }}
        display={{ base: "none", md: "flex" }}
        borderLeft="1px solid"
        borderColor="border.subtle"
        bg="bg.canvas"
        minH={0}
        position="relative"
      >
        {/* Aurora header band */}
        <Box
          px={5}
          py={3}
          bgGradient="linear(135deg, rgba(27,184,224,0.18), rgba(66,86,245,0.18) 50%, rgba(255,42,157,0.16))"
          borderBottom="1px solid"
          borderColor="border.subtle"
        >
          <HStack justify="space-between" align="center">
            <VStack align="flex-start" spacing={0}>
              <Heading
                size="sm"
                fontWeight={600}
                bgGradient="linear(135deg, cyan.300, accent.300, magenta.300)"
                bgClip="text"
                letterSpacing="-0.01em"
              >
                Eugene Workspace
              </Heading>
              <Text fontSize="11px" color="text.muted">
                Reasoning graph · evidence · lineage
              </Text>
            </VStack>
            <HStack spacing={2} fontSize="11px" color="text.muted">
              <Badge
                bg="surface.300"
                color="text.primary"
                borderRadius="md"
                px={2}
                py={0.5}
                fontWeight={500}
              >
                {nodeCount} nodes
              </Badge>
              <Badge
                bg="surface.300"
                color="text.primary"
                borderRadius="md"
                px={2}
                py={0.5}
                fontWeight={500}
              >
                {edgeCount} edges
              </Badge>
            </HStack>
          </HStack>
        </Box>

        <Tabs
          index={tabIndex}
          onChange={setTabIndex}
          variant="line"
          colorScheme="accent"
          isLazy
          lazyBehavior="keepMounted"
          flex={1}
          display="flex"
          flexDirection="column"
          minH={0}
        >
          <TabList
            px={3}
            borderBottom="1px solid"
            borderColor="border.subtle"
            overflowX="auto"
            sx={{
              "&::-webkit-scrollbar": { display: "none" },
            }}
          >
            <WorkspaceTab label="Graph" badge={nodeCount} />
            <WorkspaceTab label="Evidence" badge={evidenceCount || undefined} />
            <WorkspaceTab label="Lineage" />
            <WorkspaceTab label="Tool Calls" badge={toolCalls.length || undefined} />
            <WorkspaceTab label="Stats" />
          </TabList>

          <TabPanels flex={1} minH={0} display="flex" flexDirection="column">
            {/* ── Tab 1: Graph canvas + toolbar + legend ── */}
            <TabPanel p={0} flex={1} minH={0} position="relative">
              <Flex direction="column" h="100%" minH={0}>
                <Box
                  px={3}
                  py={2}
                  borderBottom="1px solid"
                  borderColor="border.subtle"
                  bg="bg.panel"
                >
                  <GraphToolbar
                    layout={explorer.layout}
                    onLayoutChange={explorer.setLayout}
                    source={explorer.source}
                    sink={explorer.sink}
                    onClearSource={explorer.clearSource}
                    onClearSink={explorer.clearSink}
                    onFindPath={explorer.runPathFinder}
                    finding={explorer.findingPath}
                    nodeCount={nodeCount}
                    edgeCount={edgeCount}
                    searchQuery={explorer.searchQuery}
                    onSearchChange={explorer.setSearchQuery}
                    allEdgeTypes={explorer.allEdgeTypes}
                    hiddenEdgeTypes={explorer.hiddenEdgeTypes}
                    onToggleEdgeType={explorer.toggleEdgeType}
                    onFit={explorer.fit}
                    onReset={explorer.resetGraph}
                    onExpandAll={explorer.expandAll}
                    onExportPng={explorer.exportPng}
                  />
                </Box>

                {explorer.error && (
                  <Alert
                    status="warning"
                    mx={3}
                    mt={2}
                    bg="signal.warning"
                    color="surface.0"
                    fontSize="xs"
                    borderRadius="lg"
                    py={1.5}
                    px={3}
                  >
                    <AlertIcon boxSize="12px" />
                    {explorer.error}
                  </Alert>
                )}

                <Box flex={1} minH={0} position="relative" overflow="hidden">
                  <KnowledgeGraph
                    graph={graph}
                    layout={explorer.layout}
                    selectedNodeId={explorer.selectedNodeId}
                    highlightedPathNodeIds={explorer.highlightedPathNodeIds}
                    searchQuery={explorer.searchQuery}
                    hiddenEdgeTypes={explorer.hiddenEdgeTypes}
                    onCyReady={explorer.setCyHandle}
                    onSelectNode={explorer.setSelectedNodeId}
                    onExpand={explorer.expand}
                    onMarkSource={explorer.markSource}
                    onMarkSink={explorer.markSink}
                    onClearRoles={explorer.clearRoles}
                    onShowEvidence={(id) => {
                      explorer.showEvidence(id);
                      setTabIndex(1);
                    }}
                    onTogglePin={explorer.togglePin}
                    onRemove={explorer.removeNode}
                  />
                  {/* Selected-node side drawer remains as glass overlay
                      when the user clicks a node — but lives only inside
                      the Graph tab so it doesn't follow tab changes. */}
                  <NodeDetailsPanel
                    node={
                      evidenceCount === 0 ? explorer.selectedNode : null
                    }
                    onClose={() => explorer.setSelectedNodeId(null)}
                  />
                </Box>

                <Box
                  borderTop="1px solid"
                  borderColor="border.subtle"
                  bg="bg.panel"
                >
                  <GraphLegend />
                </Box>
              </Flex>
            </TabPanel>

            {/* ── Tab 2: Evidence ── */}
            <TabPanel p={0} flex={1} minH={0}>
              {evidenceCount > 0 ? (
                <EvidencePanel
                  chain={explorer.evidenceChain}
                  onClose={() => {
                    explorer.clearEvidence();
                    setTabIndex(0);
                  }}
                />
              ) : (
                <EmptyTab
                  title="No evidence selected"
                  body="Right-click a node in the Graph tab and choose “🔎 Evidence” to drill into its supporting facts and citations."
                />
              )}
            </TabPanel>

            {/* ── Tab 3: Lineage ── */}
            <TabPanel p={0} flex={1} minH={0} overflowY="auto">
              <LineageView
                conversationId={conversationId}
                messages={messages}
              />
            </TabPanel>

            {/* ── Tab 4: Tool Calls ── */}
            <TabPanel p={0} flex={1} minH={0} overflowY="auto">
              {toolCalls.length === 0 ? (
                <EmptyTab
                  title="No tool calls yet"
                  body="The agent's tool invocations will appear here in chronological order, showing inputs, outputs, latency, and the subgraph each call contributed."
                />
              ) : (
                <Box px={4} py={3}>
                  {toolCalls.map((t, i) => {
                    const inputStr =
                      typeof t.input === "string" ? t.input : JSON.stringify(t.input);
                    const outputStr =
                      typeof t.output === "string"
                        ? t.output
                        : t.output !== undefined
                        ? JSON.stringify(t.output)
                        : "";
                    return (
                      <Box
                        key={`${t.toolId ?? i}`}
                        mb={3}
                        p={3}
                        bg="bg.surface"
                        border="1px solid"
                        borderColor="border.subtle"
                        borderRadius="lg"
                      >
                        <HStack mb={1} spacing={2}>
                          <Badge
                            colorScheme="cyan"
                            variant="subtle"
                            fontSize="10px"
                            px={2}
                          >
                            {t.tool ?? "tool"}
                          </Badge>
                          <Text fontSize="11px" color="text.subtle">
                            #{i + 1}
                          </Text>
                        </HStack>
                        {inputStr && (
                          <Text
                            fontFamily="mono"
                            fontSize="11px"
                            color="text.muted"
                            whiteSpace="pre-wrap"
                            mb={1}
                          >
                            {"→ " + inputStr}
                          </Text>
                        )}
                        {outputStr && (
                          <Text
                            fontFamily="mono"
                            fontSize="11px"
                            color="text.primary"
                            whiteSpace="pre-wrap"
                          >
                            {"← " +
                              outputStr.slice(0, 320) +
                              (outputStr.length > 320 ? " …" : "")}
                          </Text>
                        )}
                      </Box>
                    );
                  })}
                </Box>
              )}
            </TabPanel>

            {/* ── Tab 5: Stats ── */}
            <TabPanel p={0} flex={1} minH={0} overflowY="auto">
              <StatsView
                nodeCount={nodeCount}
                edgeCount={edgeCount}
                evidenceCount={evidenceCount}
                toolCallCount={toolCalls.length}
                edgeTypes={explorer.allEdgeTypes}
              />
            </TabPanel>
          </TabPanels>
        </Tabs>
      </Flex>
    </Flex>
  );
}

// ---------------------------------------------------------------------------
// Tab pill — line variant with optional badge.
// ---------------------------------------------------------------------------
function WorkspaceTab({
  label,
  badge,
}: {
  label: string;
  badge?: number;
}) {
  return (
    <Tab
      fontSize="13px"
      fontWeight={500}
      color="text.muted"
      _selected={{
        color: "text.primary",
        borderBottom: "2px solid",
        borderColor: "accent.solid",
      }}
      _hover={{ color: "text.primary" }}
      px={3}
      py={2}
    >
      {label}
      {typeof badge === "number" && badge > 0 && (
        <Badge
          ml={2}
          fontSize="10px"
          colorScheme="accent"
          variant="subtle"
          borderRadius="md"
          px={1.5}
        >
          {badge}
        </Badge>
      )}
    </Tab>
  );
}

// ---------------------------------------------------------------------------
// Empty-state for tabs.
// ---------------------------------------------------------------------------
function EmptyTab({ title, body }: { title: string; body: string }) {
  return (
    <VStack
      h="100%"
      justify="center"
      align="center"
      color="text.muted"
      px={10}
      py={6}
      spacing={3}
    >
      <Box
        w="80px"
        h="80px"
        borderRadius="full"
        bgGradient="radial(rgba(66,86,245,0.4), transparent 70%)"
        opacity={0.6}
      />
      <Text fontSize="sm" fontWeight={600} color="text.primary">
        {title}
      </Text>
      <Text fontSize="xs" textAlign="center" maxW="380px">
        {body}
      </Text>
    </VStack>
  );
}

// ---------------------------------------------------------------------------
// Lineage view — placeholder, renders the user/assistant turn timeline.
// ---------------------------------------------------------------------------
function LineageView({
  conversationId,
  messages,
}: {
  conversationId: string | null;
  messages: { id: string; role: string; content?: string; createdAt?: number }[];
}) {
  const turns = messages.filter((m) => m.role !== "system");
  if (turns.length === 0) {
    return (
      <EmptyTab
        title="No conversation yet"
        body="Send a question in the chat to start a reasoning lineage. Each user / assistant turn will appear here with timestamps and routing decisions."
      />
    );
  }
  return (
    <Box px={4} py={3}>
      <Text fontSize="11px" color="text.subtle" mb={3} fontFamily="mono">
        conversation_id: {conversationId ?? "—"}
      </Text>
      {turns.map((m, i) => (
        <Box
          key={m.id}
          mb={3}
          pl={4}
          borderLeft="2px solid"
          borderColor={m.role === "user" ? "cyan.400" : "magenta.400"}
        >
          <HStack mb={1} spacing={2}>
            <Badge
              colorScheme={m.role === "user" ? "cyan" : "purple"}
              variant="subtle"
              fontSize="10px"
              px={2}
            >
              {m.role}
            </Badge>
            <Text fontSize="11px" color="text.subtle">
              turn {i + 1}
            </Text>
          </HStack>
          <Text fontSize="13px" color="text.primary" whiteSpace="pre-wrap">
            {(m.content ?? "").slice(0, 320)}
            {(m.content ?? "").length > 320 && " …"}
          </Text>
        </Box>
      ))}
    </Box>
  );
}

// ---------------------------------------------------------------------------
// Stats view — quick-glance metrics cards.
// ---------------------------------------------------------------------------
function StatsView({
  nodeCount,
  edgeCount,
  evidenceCount,
  toolCallCount,
  edgeTypes,
}: {
  nodeCount: number;
  edgeCount: number;
  evidenceCount: number;
  toolCallCount: number;
  edgeTypes: string[];
}) {
  const cards = [
    { label: "Graph nodes", value: nodeCount, accent: "cyan.400" },
    { label: "Graph edges", value: edgeCount, accent: "accent.400" },
    { label: "Evidence facts", value: evidenceCount, accent: "magenta.400" },
    { label: "Tool calls", value: toolCallCount, accent: "lumen.500" },
  ];
  return (
    <Box px={4} py={4}>
      <HStack spacing={3} mb={4} flexWrap="wrap">
        {cards.map((c) => (
          <Box
            key={c.label}
            flex="1 1 140px"
            minW="140px"
            p={3}
            bg="bg.surface"
            border="1px solid"
            borderColor="border.subtle"
            borderRadius="lg"
            position="relative"
            overflow="hidden"
          >
            <Box
              position="absolute"
              top={0}
              left={0}
              right={0}
              h="2px"
              bg={c.accent}
            />
            <Text fontSize="10px" color="text.subtle" mb={1} letterSpacing="0.04em">
              {c.label.toUpperCase()}
            </Text>
            <Text
              fontSize="22px"
              fontWeight={600}
              color="text.primary"
              fontFamily="mono"
            >
              {c.value}
            </Text>
          </Box>
        ))}
      </HStack>

      {edgeTypes.length > 0 && (
        <Box>
          <Text fontSize="11px" color="text.subtle" mb={2} letterSpacing="0.04em">
            EDGE TYPES IN GRAPH
          </Text>
          <HStack spacing={2} flexWrap="wrap">
            {edgeTypes.map((t) => (
              <Badge
                key={t}
                bg="surface.300"
                color="text.primary"
                borderRadius="md"
                px={2}
                py={0.5}
                fontSize="11px"
                fontWeight={500}
              >
                {t}
              </Badge>
            ))}
          </HStack>
        </Box>
      )}
    </Box>
  );
}
